using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Log;
using GrapeCity.Forguncy.Plugin;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json;
using System.Threading.Tasks;

namespace FaissOperation
{
    [Icon("pack://application:,,,/FaissOperation;component/Resources/Icon.png")]
    [Designer("FaissOperation.Designer.FaissOperationServerCommandDesigner, FaissOperation")]
    [Category("嵌入式向量索引")]
    [OrderWeight(810)]
    public class Cluster_Train : Command, ICommandExecutableInServerSideAsync
    {
        [FormulaProperty]
        [DisplayName("集合名（限Faiss IVF索引）")]
        public object KBName { get; set; }

        [FormulaProperty]
        [DisplayName("向量维度")]
        public object Dimension { get; set; } = 1024;

        [FormulaProperty]
        [DisplayName("聚类的簇数（nlist）")]
        public object NList { get; set; } = 128;

        [FormulaProperty]
        [DisplayName("用于训练的向量")]
        [Description("向量的数组，形如[[0.1,0.2],[0.1,0.3]]（两个训练用向量，分别为[0.1,0.2]和[0.1,0.3]）")]
        public object FLATTENFLOAT { get; set; }

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var name = (await dataContext.EvaluateFormulaAsync(KBName))?.ToString() ?? "";
            var dim = (await dataContext.EvaluateFormulaAsync(Dimension))?.ToString() ?? "1024";
            var nlist = (await dataContext.EvaluateFormulaAsync(NList))?.ToString() ?? "128";
            var data = (await dataContext.EvaluateFormulaAsync(FLATTENFLOAT))?.ToString() ?? "";

            if (string.IsNullOrEmpty(name))
            {
                throw new Exception("集合名不能为空，请检查输入。");
            }

            if (!CollectionManager.Instance.CollectionExists(name))
            {
                throw new Exception("当前向量集合尚未被加载，请先调用【加载向量集合】然后执行本操作。");
            }

            if (!string.IsNullOrEmpty(data))
            {
                var arr = GeneralConverter.To2DVectors(data);
                CollectionManager.Instance.GetCollection(name).Train(arr);
            }

            return new ExecuteResult();
        }

        public override string ToString()
        {
            return "训练向量集合";
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }

    }
}
